package cn.semes.basic.service.impl;

import cn.semes.basic.config.BussinessException;
import cn.semes.basic.constant.RegisterCon;
import cn.semes.basic.domain.GetEmailCodeDto;
import cn.semes.basic.domain.GetPhoneCodeDto;
import cn.semes.basic.service.IVerifyCodeService;
import cn.semes.basic.util.StrUtils;
import cn.semes.basic.util.VerifyCodeUtils;
import cn.semes.user.domain.User;
import cn.semes.user.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements IVerifyCodeService {
    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;


    @Override
    public String graph(String imageCodeKey) throws IOException {
        // 生成一个4位数的验证码，生成复杂的4位随机字符串
        String randomString = StrUtils.getComplexRandomString(1);
        // 将验证码转换成base64, 100宽，50高，最后一个要转换的字符穿
        String base64Image = VerifyCodeUtils.VerifyCode(100, 50, randomString);
        // 存到reids中 5为分钟，minutes
        redisTemplate.opsForValue().set(imageCodeKey, randomString, 5, TimeUnit.MINUTES);

        return base64Image;
    }

    @Override
    public void GetCode(GetPhoneCodeDto dto) {
        // 1,参数通过注解校验
// 2,判断手机号是否注册
        User user = userMapper.findByPhone(dto.getPhone());
        if (user != null) {
            throw new BussinessException("手机账号已注册");
        }
        verify(dto.getImageCodeKey(),dto.getImageCodeValue(),dto.getPhone());

        // 7,发送短信或者发送邮件
//        SMsgUtil.sendMsg(dto.getPhone(),"您的验证码为："+smsCode+"三分钟内有效");

    }

    @Override
    public void getEmailCode(GetEmailCodeDto dto) {
        User user = userMapper.findByEmail(dto.getEmail());
        if (user != null) {
            throw new BussinessException("邮箱账号已注册");
        }
        verify(dto.getImageCodeKey(),dto.getImageCodeValue(),dto.getEmail());
    }

    private void verify(String imageKey,String imageValue,String count) {
        // 3,判断图形验证码是否正确
        String redisimagecode = (String) redisTemplate.opsForValue().get(imageKey);
        if (StringUtils.isBlank(redisimagecode) || !redisimagecode.equalsIgnoreCase(imageValue)) {
            throw new BussinessException("图形验证码错误");
        }
// 4,判断两次获取是否大于60秒，getExpire
        Long ttl = redisTemplate.getExpire(String.format(RegisterCon.REGISTER_KEY, count));
        if (ttl != null && ttl > (RegisterCon.PHONE_CODE_TTL - 1) * 60) {
            throw new BussinessException("请等待60秒后获取");
        }
// 5, 判断短信验证码是否过期，过期就重新生成，没过就用它
        String smsCode;
        String phoneCode = (String) redisTemplate.opsForValue().get(String.format(RegisterCon.REGISTER_KEY, count));
        if (StringUtils.isNotBlank(phoneCode)) {
            smsCode = phoneCode;
        } else {
            smsCode = StrUtils.getRandomString(4); // 简单的数字，字符串
        }

        log.info("手机号或者邮箱验证码：{}", smsCode); // 给服务器看

        // 6,存到redis

        redisTemplate.opsForValue().set(String.format(RegisterCon.REGISTER_KEY, count), smsCode, RegisterCon.PHONE_CODE_TTL, TimeUnit.MINUTES);
    }




}
